package com.mtw.bbs.article.controller.user;



import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.mtw.bbs.article.pojo.elasticsearch.ArticleESIndex;
import com.mtw.bbs.article.pojo.entity.ArticleIndex;
import com.mtw.bbs.article.pojo.form.ArticleForm;
import com.mtw.bbs.article.pojo.vo.ArticleVo;
import com.mtw.bbs.article.pojo.vo.TopicVo;
import com.mtw.bbs.article.service.ArticleIndexService;
import com.mtw.bbs.article.service.TopicIndexService;
import com.mtw.bbs.common.web.annotation.AccessLimit;
import com.mtw.bbs.like.pojo.dto.LikeRecordDto;
import com.mtw.bbs.like.service.LikeRecordService;
import com.mtw.bbs.userAdmin.feign.FlowClient;
import com.mtw.bbs.util.ArticleComponent;
import com.mtw.bbs.util.ArticleUtils;
import com.mtw.bbs.util.ESUtils;
import com.mtw.bbs.common.core.constant.BusinessObjectType;
import com.mtw.bbs.common.core.constant.ServiceConstant;
import com.mtw.bbs.common.core.constant.SysConstant;
import com.mtw.bbs.common.core.enums.SortEnum;
import com.mtw.bbs.common.core.security.UserDetails;
import com.mtw.bbs.common.core.security.context.SecurityContextHolder;
import com.mtw.bbs.common.core.util.BeanCopyUtils;
import com.mtw.bbs.common.core.vo.Result;
import com.mtw.bbs.userAdmin.feign.UserClient;
import com.mtw.bbs.userAdmin.pojo.vo.UserInfoVo;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.client.elc.NativeQueryBuilder;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.*;
import org.springframework.web.bind.annotation.*;
import java.util.*;


/**
 * 用户文章接口层
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("user/article")
public class UserArticleController {


    private final UserClient userClient;
    private final FlowClient flowClient;
    private final ArticleComponent articleComponent;
    private final TopicIndexService topicIndexService;
    private final LikeRecordService likeRecordService;
    private final ArticleIndexService articleIndexService;
    private final ElasticsearchTemplate elasticsearchTemplate;



    /**
     * 关注用户文章分页查询文章
     *
     * @param page        当前页
     * @param size        分页大小
     */
    @AccessLimit(second = 30,maxTime = 20)
    @GetMapping("/flow")
    public Result getFlowUserArticle(@RequestParam(name = "page") int page,
                                     @RequestParam(name = "size") int size) {

        // 当前用户
        UserDetails user = SecurityContextHolder.getContext().getAuthentication();
        List<String> uidList = flowClient.getFlowUserById(user.getId()).getData();

        if (CollectionUtil.isEmpty(uidList)){
            return Result.success(new Page<>());
        }

        LambdaQueryWrapper<ArticleIndex> lqw = new LambdaQueryWrapper<>();
        lqw.eq(ArticleIndex::getStatus, ServiceConstant.STATUS_ENABLE);
        lqw.eq(ArticleIndex::getApproveStatus, SysConstant.DEFAULT_ENABLE);
        lqw.orderByDesc(ArticleIndex::getCreatedDate);

        if(CollectionUtil.isNotEmpty(uidList)){
            List<List<String>> newList = Lists.partition(uidList, 999);
            if(newList.size() == 1){
                lqw.in(ArticleIndex::getCreatedBy, newList.get(0));
            }
            lqw.and(i ->{
                for(List<String> list: newList){
                    i.or().in(ArticleIndex::getCreatedBy, list);
                }
            });
        }

        Page<ArticleVo> voPage = articleIndexService.getArticlePage(page, size, lqw);

        return Result.success(voPage);
    }



    /**
     * 话题文章分页查询文章
     *
     * @param page        当前页
     * @param size        分页大小
     */
    @GetMapping("/index")
    public Result getIndexArticle(@RequestParam(name = "page") int page,
                                  @RequestParam(name = "size") int size,
                                  @RequestParam(name = "sort", required = false) Integer sort) {


        // 当前用户
        UserDetails user = SecurityContextHolder.getContext().getAuthentication();

        LambdaQueryWrapper<ArticleIndex> lqw = new LambdaQueryWrapper<>();
        lqw.eq(ArticleIndex::getCreatedBy, user.getId());

        if (SortEnum.SORT_LIKE.getCode().equals(sort)) {
//            qw.orderByDesc("ai.like_count");
        } else {
            lqw.orderByDesc(ArticleIndex::getCreatedDate);
        }

        Page<ArticleVo> voPage = articleIndexService.getArticlePage(page, size, lqw);

        return Result.success(voPage);
    }


    /**
     * 搜索文章
     *
     * @param page 当前页
     * @param size 分页大小
     * @param key  关键词
     */
    @GetMapping("/search")
    public Result searchData(@RequestParam(name = "page") int page,
                             @RequestParam(name = "size") int size,
                             @RequestParam(name = "key") String key) {

        if (StringUtils.isBlank(key)) {
            return Result.fail("请输入关键词");
        }

        UserDetails user = SecurityContextHolder.getContext().getAuthentication();

        //高亮查询
        HighlightQuery highlightQuery = ESUtils.getHighlightQuery(ArticleESIndex.class, "content");

        // 查询构建
        NativeQueryBuilder builder = new NativeQueryBuilder();
        builder.withHighlightQuery(highlightQuery);
        builder.withQuery(q -> q.match(m -> m.field("content").query(key)));
        builder.withFilter(f -> f.term(m -> m.field("createdBy").value(user.getId())));
        // 分页
        builder.withPageable(PageRequest.of(page - 1, size));
        builder.withSort(Sort.by(Sort.Direction.DESC, "createdDate"));

        // es搜索结果
        SearchHits<ArticleESIndex> result = elasticsearchTemplate.search(builder.build(), ArticleESIndex.class);
        // 无命中的数据
        if (!result.hasSearchHits()) {
            return Result.success(new Page<>(page, size, 0));
        }

        Page<ArticleVo> voPage = new Page<>(page, size, result.getTotalHits());

        // 发帖人id
        List<String> uidList = result.getSearchHits().stream().map(x->x.getContent().getCreatedBy()).toList();
        // 获取发帖人信息
        Map<String, UserInfoVo> posterVoMap = ArticleUtils.getUserInfoVoMap2R(userClient.getUserInfoByIds(uidList.toArray(String[]::new)));

        List<ArticleVo> voList = result.getSearchHits().stream().map(x -> {
            ArticleVo vo = BeanCopyUtils.copyBean(x.getContent(), ArticleVo.class);
            // 发帖人信息
            vo.setPoster(posterVoMap.get(x.getContent().getCreatedBy()));
            // 回写高亮字段
            vo.setContent(x.getHighlightFields().get("content").get(0));
            // 话题信息
            TopicVo topicInfo = topicIndexService.getTopicInfo(x.getContent().getTopicId());
            vo.setTopicInfo(topicInfo);
            return vo;
        }).toList();

        articleComponent.setArticleSubject(voList,user == null?null:user.getId());
        voPage.setRecords(voList);

        return Result.success(voPage);
    }




    /**
     * 获取点赞的文章
     *
     * @param page 当前页
     * @param size 分页大小
     */
    @GetMapping("/like")
    public Result getLikeList(@RequestParam(name = "page") int page,
                             @RequestParam(name = "size") int size) {


        UserDetails user = SecurityContextHolder.getContext().getAuthentication();

        LikeRecordDto dto = new LikeRecordDto();
        dto.setUserMid(user.getId());
        dto.setObjectType(BusinessObjectType.ARTICLE);
        List<String> result = likeRecordService.getLikedListByUser(page, size, dto);

        if (CollectionUtil.isEmpty(result)){
            return Result.success(new Page<>(page, size, 0));
        }

        LambdaQueryWrapper<ArticleIndex> lqw = new LambdaQueryWrapper<>();
        lqw.in(ArticleIndex::getId, result);

        Page<ArticleVo> voPage = articleIndexService.getArticlePage(page, size, lqw);

        return Result.success(voPage);
    }







    /**
     * 保存文章
     */
    @PostMapping("/save")
    public Result saveArticle(@RequestBody ArticleForm form) {


        form.setLevel(0);
        form.setApproveStatus(SysConstant.DEFAULT_ENABLE);
        form.setStatus(SysConstant.DEFAULT_ENABLE);

        String saved = articleIndexService.saveArticle(form);
        boolean result = saved != null;
        return result ? Result.success(saved) : Result.fail("保存失败");
    }





    /**
     * 修改文章
     */
    @PutMapping("/update")
    public Result updateArticle(@RequestBody ArticleForm form) {

        boolean updated = articleIndexService.updateArticleByAuthor(form);
        return updated ? Result.success() : Result.fail("更新失败");
    }





    /**
     * 删除文章
     *
     * @param id 文章id
     */
    @DeleteMapping("/delete/{id}")
    public Result deleteArticle(@PathVariable String id) {

        boolean result = articleIndexService.deleteArticleByAuthor(id);
        return result ? Result.success() : Result.fail("删除失败");
    }





    /**
     * 禁用文章，即设为私密
     */
    @PutMapping("/disable/{id}")
    public Result disableArticle(@PathVariable String id) {

        ArticleForm form = new ArticleForm();
        form.setId(id);
        form.setStatus(ServiceConstant.STATUS_DISABLE);
        boolean updated = articleIndexService.updateArticleByAuthor(form);
        return updated ? Result.success() : Result.fail("设置失败");
    }

}
